package com.icim.csot.exporter.job;

import java.io.File;
import java.sql.Timestamp;
import java.util.*;

import javax.annotation.Resource;

import com.icim.util.HCutil;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.icim.core.pojo.FtpConfigure;
import com.icim.core.service.IAlarmSenderService;
import com.icim.core.service.IFtpService;
import com.icim.csot.exporter.csventity.CsotSpcDataCsvEntity;
import com.icim.dao.RetCusPrdIndtDao;
import com.icim.dao.RetCusSoDao;
import com.icim.dao.RetPrdInfoDao;
import com.icim.dao.RetWoDao;
import com.icim.dao.SpcRetMfgDataDao;
import com.icim.def.ComDef;
import com.icim.entity.Ret_prd_info;
import com.icim.entity.Spc_ret_mfg_data;
import com.icim.util.CsvFileWriterUtil;
import com.icim.util.GzCompressUtil;
import com.icim.util.TimeUtil;
import static com.icim.def.ComDef.*;

/**
 * export SPC data with parameter name CDPC && CZPC send to CSOT FTP Service
 * 
 * @author XINLIN
 *
 */
public class CsotExportSpcMfgDataJob {

    private final static Logger logger = LoggerFactory.getLogger(CsotExportSpcMfgDataJob.class);

    private Timestamp beginTimestamp;
    private Timestamp endTimestamp;
    private FtpConfigure ftpConfigure;
    private int endTimeMak;
    private String strEndTime;

    @Resource
    private RetPrdInfoDao retPrdInfoDao;
    @Resource
    private SpcRetMfgDataDao spcRetMfgDataDao;

    private IFtpService ftpService;
    
    @Resource
    private IAlarmSenderService alarmSenderService;

    public void subMainProc() {
        logger.info("export spc mfg data system running .....");
        /**
         * get time period : begin time & end time
         */
       

        /**
         * don't get begin && end time use it for jUnit test
         */
        try {
        	getTimePeriod();
			subMainProc2();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			String errorMsg="spc数据回传失败，开始时间："+beginTimestamp+"  结束时间："+endTimestamp+"\n"+"失败原因："+e.getMessage();
        	alarmSenderService.sendAlarm1("007",errorMsg);
		}

        logger.info("export history successfull ......");
    }

    public void subMainProc2() throws Exception {

        /**
         * get SPC data recorders of cus_id:007 . query table SPC_RET_MFG_DATA,
         */

        List<Spc_ret_mfg_data> spcRetMfgDataList = spcRetMfgDataDao.getCsotSpcDataRecorders(beginTimestamp,
                endTimestamp, new String[] { "JS-BH-0IQC","JS-BH-0YCJ", "JS-DM-0CPJ","JS-DM-00CJ" }, "CDPC", "CZPC", ComDef.CUS_ID);
        logger.info("find {} records in SPC_RET_MFG_DATA ", spcRetMfgDataList.size());
        if (spcRetMfgDataList.size() == 0) {
            return;
        }

        HashMap<String,Spc_ret_mfg_data> spc_ret_mfg_dataHashMap= new HashMap<>();
        for(int i = 0 ;i < spcRetMfgDataList.size(); i++){
            String prdSeqId = spcRetMfgDataList.get(i).getPrd_seq_id_fk();
            String mesIdFk = spcRetMfgDataList.get(i).getMes_id_fk();
            String opeIdFk = spcRetMfgDataList.get(i).getOpe_id_fk();
            String key = prdSeqId+"_"+mesIdFk+"_"+opeIdFk;
            if(spc_ret_mfg_dataHashMap.containsKey(key)){
                //再判断已存在的，上报时间，取最新的
                if (HCutil.getDiffMillisec(spc_ret_mfg_dataHashMap.get(key).getRpt_timestamp(), spcRetMfgDataList.get(i).getRpt_timestamp()) > 0) {
                    spc_ret_mfg_dataHashMap.put(key, spcRetMfgDataList.get(i));
                }
            } else {
                spc_ret_mfg_dataHashMap.put(key, spcRetMfgDataList.get(i));
            }
        }

        List<Spc_ret_mfg_data> spcRetMfgDataList2 = new ArrayList<>();
        Iterator iter2 = spc_ret_mfg_dataHashMap.entrySet().iterator();        //获取key和value的set
        while (iter2.hasNext()) {
            Map.Entry entry = (Map.Entry) iter2.next();        //把hashmap转成Iterator再迭代到entry
            Object key = entry.getKey();        //从entry获取key
            Object val = entry.getValue();    //从entry获取value
            spcRetMfgDataList2.add((Spc_ret_mfg_data) val);
        }

        Set<String> sheetIdSet = new HashSet<String>();
        for (Spc_ret_mfg_data spcRetMfgData : spcRetMfgDataList2) {
            sheetIdSet.add(spcRetMfgData.getPrd_seq_id_fk());
        }
        /**
         * get all sheets by cus_id query table RET_PRD_INFO by custom_id & time
         * period select * from ret_prd_info where wo_id_fk in ( select wo_id
         * from ret_wo where cus_id = '007')
         */

        List<Ret_prd_info> retPrdInfoList = retPrdInfoDao.getSheetList(sheetIdSet);
        for (Ret_prd_info retPrdInfo : retPrdInfoList) {

            List<CsotSpcDataCsvEntity> spcDataEntityList = new ArrayList<CsotSpcDataCsvEntity>();
            for (Spc_ret_mfg_data spcRetMfgData : spcRetMfgDataList2) {
                if (spcRetMfgData.getPrd_seq_id_fk().equals(retPrdInfo.getPrd_seq_id())) {

                    try {

                        /**
                         * convert one record to many process , if it's
                         * data_value_XXX is not blank
                         */
                        List<Spc_ret_mfg_data> convertedSpcRetMfgDataList = spcRetMfgData.converToList();

                        for (int index = 0; index < convertedSpcRetMfgDataList.size(); index++) {
                            Spc_ret_mfg_data convertedSpcRetMfgData = convertedSpcRetMfgDataList.get(index);
                            CsotSpcDataCsvEntity spcDataEntity = new CsotSpcDataCsvEntity();
                            spcDataEntity.setBLOCK_ID(convertedSpcRetMfgData.getPrd_seq_id_fk());
                            spcDataEntity.setFACTORY_ID(CSOT_FACTORY_NAME);
                            spcDataEntity.setPRODUCT_ID(retPrdInfo.getMdl_id_fk());
                            spcDataEntity.setOWNER_CODE(retPrdInfo.getGroup_id());
                            spcDataEntity.setPROCESS(convertedSpcRetMfgData.getOpe_id_fk());
                            spcDataEntity.setEQ_ID(convertedSpcRetMfgData.getTool_id_fk());
                            spcDataEntity.setDATE(convertedSpcRetMfgData.getRpt_timestamp().toString().substring(0, 10)
                                    .replace("-", "/"));
                            spcDataEntity.setTIME(convertedSpcRetMfgData.getRpt_timestamp().toString()
                                    .substring(11, 19));
                            spcDataEntity.setSPC_PARAM(convertedSpcRetMfgData.getMes_id_fk());
                            spcDataEntity.setSITE_NAME(String.valueOf(index + 1));
                            spcDataEntity.setVALUE(convertedSpcRetMfgData.getData_value());
                            spcDataEntityList.add(spcDataEntity);
                        }

                    } catch (Exception e) {
                        logger.error(e.toString());
                        throw e;
                    }

                }
            }
            // build CSV file by spcDataEntityList
            String currentTime = TimeUtil.getRvTime();

            String fileName = getFtpConfigure().getLocalSpcGzPath() + "/SPC_" + retPrdInfo.getPrd_seq_id() + "_"
                    + strEndTime + ".csv";
            // compress file to *.gz
            String[] headers = { "BLOCK_ID", "FACTORY_ID", "PRODUCT_ID", "OWNER_CODE", "PROCESS", "EQ_ID", "DATE",
                    "TIME", "SPC_PARAM", "SITE_NAME", "VALUE" };

            List<String[]> bodyList = new ArrayList<String[]>();
            for (CsotSpcDataCsvEntity spcDataEntity : spcDataEntityList) {
                String[] body = new String[] { spcDataEntity.getBLOCK_ID(), spcDataEntity.getFACTORY_ID(),
                        spcDataEntity.getPRODUCT_ID(), spcDataEntity.getOWNER_CODE(), spcDataEntity.getPROCESS(),
                        spcDataEntity.getEQ_ID(), spcDataEntity.getDATE(), spcDataEntity.getTIME(),
                        spcDataEntity.getSPC_PARAM(), spcDataEntity.getSITE_NAME(), spcDataEntity.getVALUE()

                };
                logger.info(spcDataEntity.toString());
                bodyList.add(body);

            }
            try {

                logger.info("building csv File process [" + fileName + "]");
                CsvFileWriterUtil.writeCVS("SLIM_SPC_DATA_BEGIN", headers, bodyList, "SLIM_SPC_DATA_END", fileName);

                logger.info("compress csv file process ....");
                GzCompressUtil.compress(new File(fileName));
                String gzFileName = fileName + ".gz";
                File gzFile = new File(gzFileName);

                // send to FTP Service
                ftpService.connect();
                ftpService.uploadFile(gzFile, getFtpConfigure().getFtpSpcExportPath());
                ftpService.disconnectFtp();

            } catch (Exception e) {
                logger.error(e.toString());
                throw e;
            }
        }

    }

    /**
     * 
     */
    private void getTimePeriod() {
        DateTime dt = new DateTime();

        DateTime endDt = dt.plusMinutes(endTimeMak);
        endTimestamp = new Timestamp(endDt.getMillis());

        DateTime beginDt = endDt.plusHours(-1);
        beginTimestamp = new Timestamp(beginDt.getMillis());

        strEndTime = getTimeFromDateTime(endDt);
        
        logger.info("begin time:" + beginTimestamp);
        logger.info("end time :" + endTimestamp);
    }
    
    private String getTimeFromDateTime(DateTime dt) {
      return comInt2String(dt.getYear(), 4) + comInt2String(dt.getMonthOfYear(), 2)
               + comInt2String(dt.getDayOfMonth(), 2) + comInt2String(dt.getHourOfDay(), 2)
               + comInt2String(dt.getMinuteOfHour(), 2) + comInt2String(dt.getSecondOfMinute(),2);
    }

    public static void main(String[] args) {
        new CsotExportSpcMfgDataJob().getTimePeriod();
    }

    public Timestamp getBeginTimestamp() {
        return beginTimestamp;
    }

    public void setBeginTimestamp(Timestamp beginTimestamp) {
        this.beginTimestamp = beginTimestamp;
    }

    public Timestamp getEndTimestamp() {
        return endTimestamp;
    }

    public void setEndTimestamp(Timestamp endTimestamp) {
        this.endTimestamp = endTimestamp;
    }

    public FtpConfigure getFtpConfigure() {
        return ftpConfigure;
    }

    public void setFtpConfigure(FtpConfigure ftpConfigure) {
        this.ftpConfigure = ftpConfigure;
    }

    public String comInt2String(int value, int length) {
        String s = String.valueOf(value);
        if (s.length() > length) {
            throw new RuntimeException("length is too short.");
        } else if (s.length() == length) {
            return s;
        } else {
            char[] cc = new char[length];
            int i = 0;
            for (; i < length - s.length(); i++) {
                cc[i] = '0';
            }
            for (int j = 0; j < s.length(); i++, j++) {
                // System.out.println(i);
                cc[i] = s.charAt(j);
            }
            return new String(cc);
        }
    }

    public IFtpService getFtpService() {
        return ftpService;
    }

    public void setFtpService(IFtpService ftpService) {
        this.ftpService = ftpService;
    }
    public int getEndTimeMak() {
		return endTimeMak;
	}

	public void setEndTimeMak(int endTimeMak) {
		this.endTimeMak = endTimeMak;
	}

    public String getStrEndTime() {
      return strEndTime;
    }
    
    public void setStrEndTime(String strEndTime) {
      this.strEndTime = strEndTime;
    }


}
